﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using YinfangWeb.BLL.Enum;
using YinfangWeb.BLL.Model;
using YinfangWeb.Common;
using YinfangWeb.DAL;
using YinfangWeb.Model;

namespace YinfangWeb.BLL
{
    public class UserBO
    {
        private readonly UserDataDAO _userDataDAO = new UserDataDAO();
        private readonly UserTokenDAO _userTokenDAO = new UserTokenDAO();
        private readonly UserLogDAO _userLogDAO = new UserLogDAO();
        private readonly UserRoleDAO _userRoleDAO = new UserRoleDAO();
        private readonly UserRightItemDAO _userRightItemDAO = new UserRightItemDAO();
        private readonly UserRightDAO _userRightDAO = new UserRightDAO();

        #region 登录（用户名+密码方式）
        /// <summary>
        /// 登录（用户名+密码方式）
        /// </summary>
        /// <param name="identity">身份</param>
        /// <param name="loginName">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="ip">IP</param>
        /// <returns></returns>
        public IResult LoginByPassword(string identity, string loginName, string password, string ip)
        {
            UserData userData;
            string username = loginName.ToLower();
            userData = _userDataDAO.GetInfoByUserName(ConvertHelper.ToInt(identity), username);
            if (userData == null)
            {
                return new Result(ResultCode.AccountUserNotFound);
            }

            if (userData.UserState != (int)EnumUserData_UserState.Normal)
            {
                return new Result(ResultCode.AccountException, "登录失败。账号异常，请联系管理员");
            }
            var ss = GetEncryptPassword(userData.Salt, password);
            if (userData.UserPwd != GetEncryptPassword(userData.Salt, password))
            {
                //AddLoginFailedNum(userData, identity); 登录次数
                return new Result(ResultCode.AccountLoginError);
            }
            else
            {
                //DeleteLoginFaildNum(userData.UserDataID, identity);清空登录次数
            }

            //if (!DomainVerify(userData.UserDataID, identity, ip))
            //{
            //    return new Result(ErrorCode.DomainInvalid, "登录失败，未通过域名验证");
            //}

            var log = "用户名登录";//记录登录方式
            return LoginFinish(userData, ip, (int)EnumUserLog_LogType.Login, (int)EnumUserLog_LogPlatform.Web, log);

            //return new Result(ResultCode.Success);
        }
        #endregion

        #region Token 生成
        /// <summary>
        /// Token 生成
        /// </summary>
        /// <param name="userDataID">用户ID</param>
        /// <returns></returns>
        public string TokenInert(int userDataID)
        {
            string token = Guid.NewGuid().ToString("N");
            DateTime validDate = DateTime.Now.AddDays(1);
            var userToken = new UserToken()
            {
                UserDataID = userDataID,
                Token = token,
                ValidDateTime = validDate,
                RegDateTime = DateTime.Now,
            };
            var res = _userTokenDAO.Insert(userToken);
            if (res == 1) { return token; }
            else { return ""; }
        }
        #endregion
        #region 账号 返回账号信息 通过Token
        /// <summary>
        /// 账号 返回账号信息 通过Token
        /// </summary>
        /// <param name="userDataID">用户ID</param>
        /// <returns></returns>
        public IResult GetAccountInfoByToken(string token)
        {
            var userdata = _userDataDAO.GetInfoByToken(token);
            var account = GetAccountInfo(userdata, token);
            return new DataResult(account);
        }
        public ObjUserAccountInfo GetUserInfoByToken(string token)
        {
            var userdata = _userDataDAO.GetInfoByToken(token);
            return GetAccountInfo(userdata, token);
        }
        #endregion

        #region 权限 返回当前用户权限code项 通过Token
        /// <summary>
        /// 权限 返回当前用户权限code项 通过Token
        /// </summary>
        /// <param name="token">token</param>
        /// <returns></returns>
        public IResult GetRightCodeListByToken(string token)
        {
            var userdata = _userDataDAO.GetInfoByToken(token);
            int roleid = userdata.UserRoleID;
            var list = _userRightDAO.GetListByRole(roleid);
            
            var values = list.Where(w => w.MenuItem==true).Select(p => p.RightCode).ToList();
            return new DataResult<List<string>>(values);
        }
        #endregion
        #region 权限 返回当前角色权限代ID值
        /// <summary>
        /// 权限 返回当前角色权限项ID值
        /// </summary>
        /// <param name="roleid">角色ID</param>
        /// <returns></returns>
        public IResult GetRightIDListByRole(int roleid)
        {
            var list = _userRightDAO.GetListByRole(roleid);
            var values = list.Select(p => p.UserRightItemID).ToList();
            return new DataResult<List<int>>(values);
        }
        #endregion
        #region 权限 返回所有权限项
        /// <summary>
        /// 角色 返回所有权限项
        /// </summary>
        /// <returns></returns>
        public IResult GetRightItemAll()
        {
            var result = new List<dynamic>();
            var listfirst = _userRightItemDAO.GetListLevelfirst();
            listfirst.ForEach(first =>
            {
                var tmp = new
                {
                    id = first.UserRightItemID,
                    label = first.RightName,
                    children = GetRightItemSecond(first.UserRightItemID),
                };
                result.Add(tmp);
            });
            return new DataResult<List<dynamic>>(result);
        }
        private List<dynamic> GetRightItemSecond(int levelfirst)
        {
            var result = new List<dynamic>();
            var secondfirst = _userRightItemDAO.GetListLevelsecond(levelfirst);
            secondfirst.ForEach(second =>
            {
                var tmp = new
                {
                    id = second.UserRightItemID,
                    label = second.RightName,
                };
                result.Add(tmp);
            });
            return result;
        }
        #endregion
        #region 权限 保存当前角色权限
        /// <summary>
        /// 权限 保存当前角色权限
        /// </summary>
        /// <param name="roleid">角色id</param>
        /// <param name="list">权限列表</param>
        /// <returns></returns>
        public bool SaveRight(int roleid, List<int> list)
        {
            _userRightDAO.DeleteByRole(roleid);//先删除以前的权限
            var result = new List<UserRight>();
            list.ForEach(item =>
            {
                var tmp = new UserRight
                {
                    UserRoleID = roleid,
                    UserRightItemID = item,
                };
                result.Add(tmp);
            });
            return _userRightDAO.Insert(result) > 0;
        }
        #endregion


        #region 日志 生成
        /// <summary>
        /// 日志 生成
        /// </summary>
        /// <param name="userDataID">用户ID</param>
        /// <returns></returns>
        public bool LogInert(int userDataID, string ip, int platForm, int logType, string log)
        {
            var userLog = new UserLog()
            {
                UserDataID = userDataID,
                LogTime = DateTime.Now,
                LogIP = ip,
                LogPlatform = platForm,
                LogType = logType,
                LoginLog = log,
            };
            var res = _userLogDAO.Insert(userLog);
            if (res == 1) { return true; }
            else { return false; }
        }
        #endregion

        #region 角色 返回所有角色
        /// <summary>
        /// 角色 返回所有角色
        /// </summary>
        /// <param name="userDataID">用户ID</param>
        /// <returns></returns>
        public IResult GetRoleListKeyInfo()
        {
            var result = new List<dynamic>();
            var list = _userRoleDAO.GetListKeyInfo();
            list.ForEach(item =>
            {
                var tmp = new
                {
                    id = item.UserRoleID,
                    label = item.RoleName,
                };
                result.Add(tmp);
            });
            return new DataResult<List<dynamic>>(result);
        }
        #endregion
        

        #region 内部方法
        #region 密码 获取加密后的密码
        /// <summary>
        /// 获取加密后的密码
        /// </summary>
        /// <param name="salt"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        private string GetEncryptPassword(string salt, string password)
        {
            return SecurityHelper.Sha256Encrypt(salt + password);
        }
        #endregion
        #region 登录 成功后处理并返回的值
        /// <summary>
        /// 登录 成功后处理并返回的值
        /// </summary>
        /// <param name="userData"></param>
        /// <param name="ip"></param>
        /// <param name="logType"></param>
        /// <param name="logPlatform"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        private IResult LoginFinish(UserData userData, string ip, int logType, int logPlatform, string log)
        {
            LogInert(userData.UserDataID, ip, logType, logPlatform, log);//日志
            var token = TokenInert(userData.UserDataID);//生成token
            var account = GetAccountInfo(userData, token);//返回账号信息
            return new DataResult(account);
        }
        #endregion
        #region 账号 返回账号信息
        /// <summary>
        /// 账号 返回账号信息
        /// </summary>
        /// <param name="userData"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        private ObjUserAccountInfo GetAccountInfo(UserData userData, string token)
        {
            var returnData = new ObjUserAccountInfo
            {
                UserDataID = userData.UserDataID,
                UserName = userData.UserName,
                UserIdentity = userData.UserIdentity,
                UserRoleID = userData.UserRoleID,
                UserLogo = userData.UserLogo,
                Token = token,
            };
            return returnData;
        }
        #endregion
        #endregion



    }
}
